﻿using DailyApp.WPF.DTOs;
using DailyApp.WPF.HttpClients;
using DailyApp.WPF.Models;
using DailyApp.WPF.MsgEvents;
using DailyApp.WPF.Service;
using MaterialDesignThemes.Wpf;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using RestSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace DailyApp.WPF.ViewModels
{
    class HomeUCViewModel : BindableBase, IConfirmNavigationRequest
    {

        //client
        private readonly HttpRestClient httpRestClient;

        //对话框服务
        private readonly DialogHostService dialogHostService;

        //区域管理
        private readonly IRegionManager regionManager;

        //记录
        private IRegionNavigationJournal journal;

        //订阅事件
        private readonly IEventAggregator eventAggregator;


        //更新数据--定义为私有属性给具扩展性
        private StatWaitDTO statWaitDTO;
        private StatMemoDTO statMemoDTO;


        #region 委托命令

        //弹出添加待办事项
        public DelegateCommand ShowAddWaitCmd { get; set; }

        //弹出添加备忘录信息
        public DelegateCommand ShowAddMemoCmd { get; set; }

        //切换待办事项状态为完成
        public DelegateCommand<WaitTodoInfoDTO> ChangeWaitStatusCmd { get; set; }

        //切换备忘录事项状态为完成
        public DelegateCommand<MemoInfoDTO> ChangeMemoStatusCmd { get; set; }

        //双击修改待办事项
        public DelegateCommand<WaitTodoInfoDTO> ModifyWaitCmd { get; set; }

        //双击修改备忘录
        public DelegateCommand<MemoInfoDTO> ModifyMemoCmd { get; set; }

        //选项卡进行导航
        public DelegateCommand<StatPanelInfoModel> StatPanelNavigateCmd { get; set; }

        #endregion


        #region 属性相关

        /// <summary>
        /// 待办事项的属性
        /// </summary>
        private List<WaitTodoInfoDTO> waitTodoInfoList;
        public List<WaitTodoInfoDTO> WaitTodoInfoList
        {
            get { return waitTodoInfoList; }
            set
            {
                waitTodoInfoList = value;
                RaisePropertyChanged();
            }
        }


        /// <summary>
        /// 备忘录的属性
        /// </summary>
        private List<MemoInfoDTO> memoInfoList;
        public List<MemoInfoDTO> MemoInfoList
        {
            get { return memoInfoList; }
            set
            {
                memoInfoList = value;
                RaisePropertyChanged();
            }
        }


        /// <summary>
        /// 选项卡信息集合属性
        /// </summary>
        private List<StatPanelInfoModel> statPanelInfoList;
        public List<StatPanelInfoModel> StatPanelInfoList
        {
            get { return statPanelInfoList; }
            set
            {
                statPanelInfoList = value;
                RaisePropertyChanged();
            }
        }

        #endregion


        /// <summary>
        /// 构造函数
        /// </summary>
        public HomeUCViewModel(HttpRestClient _httpRestClient, DialogHostService _dialogHostService,
                                IRegionManager _regionManager, IRegionNavigationJournal _journal, IEventAggregator _eventAggregator)
        {
            //服务
            httpRestClient = _httpRestClient;
            dialogHostService = _dialogHostService;
            regionManager = _regionManager;
            journal = _journal;
            eventAggregator = _eventAggregator;

            //委托命令实现
            ShowAddWaitCmd = new DelegateCommand(ShowAddWaitFunc);
            ShowAddMemoCmd = new DelegateCommand(ShowAddMemoFunc);
            ChangeWaitStatusCmd = new DelegateCommand<WaitTodoInfoDTO>(ChangeWaitStatusFunc);
            ChangeMemoStatusCmd = new DelegateCommand<MemoInfoDTO>(ChangeMemoStatusFunc);
            ModifyWaitCmd = new DelegateCommand<WaitTodoInfoDTO>(ModifyWaitFunc);
            ModifyMemoCmd = new DelegateCommand<MemoInfoDTO>(ModifyMemoFunc);
            StatPanelNavigateCmd = new DelegateCommand<StatPanelInfoModel>(StatPanelNavigateFunc);

            //该异步方法簇无需关注执行顺序
            InitStatPanelInfoList();//选项卡
            InitWaitTodoInfoList();//事项表
            InitMemoInfoList();//备忘录信息
        }


        #region 具体方法

        /// <summary>
        /// 初始化选项卡信息
        /// </summary>
        private async void InitStatPanelInfoList()
        {
            StatPanelInfoList = new List<StatPanelInfoModel>()
            {
                new StatPanelInfoModel(){Icon="ClockFast",ItemName="全部",BackgroundColor="#FF0CA0FF",ViewName="WaitUC",Result=$"###"},
                new StatPanelInfoModel(){Icon="ClockCheckOutline",ItemName="已完成",BackgroundColor="#FF1ECA3A",ViewName="WaitUC",Result=$"###"},
                new StatPanelInfoModel(){Icon="ChartLineVariant",ItemName="完成比例",BackgroundColor="#FF02C6DC",ViewName="",Result=$"###%"},
                new StatPanelInfoModel(){Icon="PlaylistStar",ItemName="备忘录",BackgroundColor="#FFFFA000",ViewName="MemoUC",Result=$"###"},
            };

            //更新数据
            await Task.WhenAll(UpdateWaitDataAsync(), UpdateMemoDataAsync());
        }


        /// <summary>
        /// 更新选项卡中待办事项的数据
        /// </summary>
        private async Task UpdateWaitDataAsync()
        {
            //配置请求信息
            ApiRequest apiRequest = new ApiRequest();
            apiRequest.Method = Method.GET;
            apiRequest.Route = "Wait/StatWait";

            //请求
            var resWait = await httpRestClient.ExecuteAsync(apiRequest);

            //判断是否请求成功
            if (resWait != null && resWait.ResultCode == 1)
            {

                statWaitDTO = JsonConvert.DeserializeObject<StatWaitDTO>(resWait.ResultData.ToString());

                if (statWaitDTO != null)
                {
                    StatPanelInfoList[0].Result = statWaitDTO.TotalCount.ToString();
                    StatPanelInfoList[1].Result = statWaitDTO.FinshedCount.ToString();
                    StatPanelInfoList[2].Result = statWaitDTO.FinshedPercent;
                }
            }
        }


        /// <summary>
        /// 更新选项卡中待办事项的数据
        /// </summary>
        private async Task UpdateMemoDataAsync()
        {
            //配置请求信息
            ApiRequest apiRequest = new ApiRequest();
            apiRequest.Method = Method.GET;
            apiRequest.Route = "Memo/StatMemo";

            //请求
            var resWait = await httpRestClient.ExecuteAsync(apiRequest);

            //判断是否请求成功
            if (resWait != null && resWait.ResultCode == 1)
            {

                statMemoDTO = JsonConvert.DeserializeObject<StatMemoDTO>(resWait.ResultData.ToString());

                if (statMemoDTO != null)
                {
                    StatPanelInfoList[3].Result = statMemoDTO.TotalCount.ToString();
                }
            }
        }


        /// <summary>
        /// 添加待办事项到待办事项表中（采用整体更新的方式）
        /// </summary>
        private async Task InitWaitTodoInfoList()
        {
            WaitTodoInfoList = new List<WaitTodoInfoDTO>();

            ApiRequest apiRequest = new ApiRequest();
            apiRequest.Method = Method.GET;
            apiRequest.Route = "Wait/GetWaittingInfo";

            var res = await httpRestClient.ExecuteAsync(apiRequest);

            if (res.ResultCode == 1)
            {
                //这里转换的时候要注意后端的属性命名要和前端的一样，不然转换不了。
                WaitTodoInfoList = JsonConvert.DeserializeObject<List<WaitTodoInfoDTO>>(res.ResultData.ToString());
            }
            else
            {
                WaitTodoInfoList = new List<WaitTodoInfoDTO>();//防止空引用
            }

        }


        /// <summary>
        /// 修改编辑待办事项信息
        /// </summary>
        private async void ModifyWaitFunc(WaitTodoInfoDTO waitTodoInfoDTO)
        {
            //添加参数并传递
            var param = new DialogParameters
            {
                {"OldWait", waitTodoInfoDTO}//将旧数据传递过去
            };

            var res = await dialogHostService.ShowDialog("ModifyWaitUC", param, "RootDialog");//窗体服务

            if (res.Result == ButtonResult.OK)
            {
                //执行回调
                if (res.Parameters.ContainsKey("NewWait"))
                {
                    //调用Api储存--更新
                    ApiRequest apiRequest = new ApiRequest();
                    apiRequest.Method = Method.PUT;
                    apiRequest.Route = "Wait/ModifyWaitInfo";
                    apiRequest.Parameters = res.Parameters.GetValue<WaitTodoInfoDTO>("NewWait");

                    var resp = await httpRestClient.ExecuteAsync(apiRequest);//请求Api

                    if (resp.ResultCode == 1)
                    {
                        //更新
                        await InitWaitTodoInfoList();

                        MessageBox.Show("Modification Success!");
                    }
                    else
                    {
                        MessageBox.Show("Error!");
                    }
                }
                else
                    return;
            }
            else
            {

            }
        }


        /// <summary>
        /// 双击修改备忘录信息
        /// </summary>
        private async void ModifyMemoFunc(MemoInfoDTO memoInfoDTO)
        {

            //添加参数并传递
            var param = new DialogParameters
            {
                {"OldMemo", memoInfoDTO}//将旧数据传递过去
            };

            var res = await dialogHostService.ShowDialog("ModifyMemoUC", param, "RootDialog");//窗体服务

            if (res.Result == ButtonResult.OK)
            {
                //执行回调
                if (res.Parameters.ContainsKey("NewMemo"))
                {
                    //调用Api储存--更新
                    ApiRequest apiRequest = new ApiRequest();
                    apiRequest.Method = Method.PUT;
                    apiRequest.Route = "Memo/ModifyMemoInfo";
                    apiRequest.Parameters = res.Parameters.GetValue<MemoInfoDTO>("NewMemo");

                    var resp = await httpRestClient.ExecuteAsync(apiRequest);//请求Api

                    if (resp.ResultCode == 1)
                    {
                        //更新
                        await InitMemoInfoList();

                        MessageBox.Show("Modification Success!");
                    }
                    else
                    {
                        MessageBox.Show("Error!");
                    }
                }
                else
                    return;
            }
            else
            {

            }
        }


        /// <summary>
        /// 切换待办事项状态为完成，并更新事项表
        /// </summary>
        private async void ChangeWaitStatusFunc(WaitTodoInfoDTO waitTodoInfoDTO)
        {
            if (waitTodoInfoDTO != null)
            {
                //修改状态标志位
                waitTodoInfoDTO.Status = 1;

                //请求后端Api修改数据库信息
                ApiRequest apiRequest = new ApiRequest();
                apiRequest.Method = Method.PUT;
                apiRequest.Route = "Wait/ModifyWaitInfo";
                apiRequest.Parameters = waitTodoInfoDTO;

                var res = await httpRestClient.ExecuteAsync(apiRequest);
                if (res.ResultCode == 1)
                {
                    await Task.Delay(200);//让动画能够播完...
                    //刷新界面
                    await Task.WhenAll(InitWaitTodoInfoList(), UpdateWaitDataAsync());
                }
                else
                {
                    MessageBox.Show("服务器忙...");
                }
            }
        }


        /// <summary>
        /// 切换备忘录事项状态为完成，并更新事项表
        /// </summary>
        private async void ChangeMemoStatusFunc(MemoInfoDTO memoInfoDTO)
        {
            if (memoInfoDTO != null)
            {
                //修改状态标志位
                memoInfoDTO.Status = 1;

                //请求后端Api修改数据库信息
                ApiRequest apiRequest = new ApiRequest();
                apiRequest.Method = Method.PUT;
                apiRequest.Route = "Memo/ModifyMemoInfo";
                apiRequest.Parameters = memoInfoDTO;

                var res = await httpRestClient.ExecuteAsync(apiRequest);
                if (res.ResultCode == 1)
                {
                    await Task.Delay(200);//让动画能够播完...
                    //刷新界面
                    await Task.WhenAll(InitMemoInfoList(), UpdateMemoDataAsync());
                }
                else
                {
                    MessageBox.Show("服务器忙...");
                }
            }
        }


        /// <summary>
        /// 添加备忘录信息
        /// </summary>
        private async Task InitMemoInfoList()
        {
            MemoInfoList = new List<MemoInfoDTO>();

            ApiRequest apiRequest = new ApiRequest();
            apiRequest.Method = Method.GET;
            apiRequest.Route = "Memo/GetMemoingInfo";

            var res = await httpRestClient.ExecuteAsync(apiRequest);

            if (res.ResultCode == 1)
            {
                //这里转换的时候要注意后端的属性命名要和前端的一样，不然转换不了。
                MemoInfoList = JsonConvert.DeserializeObject<List<MemoInfoDTO>>(res.ResultData.ToString());
            }
            else
            {
                MemoInfoList = new List<MemoInfoDTO>();//防止空引用
            }
        }


        /// <summary>
        /// 弹出待办事项框的具体方法
        /// </summary>
        public async void ShowAddWaitFunc()
        {
            var res = await dialogHostService.ShowDialog("AddWaitUC", null, "RootDialog");

            //等效回调--保存现场，转而执行其他函数，异步方法执行完毕后回到现场继续执行
            if (res.Result == ButtonResult.OK)
            {
                ApiRequest apiRequest = new ApiRequest();

                //接收数据
                if (res.Parameters.ContainsKey("AddWaitInfo"))
                {
                    var waitTodoInfoDTO = res.Parameters.GetValue<WaitTodoInfoDTO>("AddWaitInfo");
                    apiRequest.Parameters = waitTodoInfoDTO;
                }
                else
                    return;

                //调用webapi
                apiRequest.Method = Method.POST;
                apiRequest.Route = "Wait/AddWaitInfo";

                var response = await httpRestClient.ExecuteAsync(apiRequest);

                if (response.ResultCode == 1)
                {
                    MessageBox.Show("添加成功!");

                    //刷新界面信息
                    await Task.WhenAll(InitWaitTodoInfoList(), UpdateWaitDataAsync());
                }
                else
                {
                    MessageBox.Show("添加失败!");
                }
            }
        }


        /// <summary>
        /// 弹出添加备忘录信息
        /// </summary>
        public async void ShowAddMemoFunc()
        {
            var res = await dialogHostService.ShowDialog("AddMemoUC", null, "RootDialog");

            if (res.Result == ButtonResult.OK)
            {
                ApiRequest apiRequest = new ApiRequest();

                //接收数据
                if (res.Parameters.ContainsKey("AddMemoInfo"))
                {
                    var memoInfoDTO = res.Parameters.GetValue<MemoInfoDTO>("AddMemoInfo");
                    apiRequest.Parameters = memoInfoDTO;
                }
                else
                    return;

                //调用api
                apiRequest.Method = Method.POST;
                apiRequest.Route = "Memo/AddMemoInfo";

                var resp = await httpRestClient.ExecuteAsync(apiRequest);

                if (resp.ResultCode == 1)
                {

                    //刷新界面信息
                    await Task.WhenAll(InitMemoInfoList(), UpdateMemoDataAsync());

                    MessageBox.Show("添加成功!");

                }
                else
                {
                    MessageBox.Show("添加失败!");
                }

            }
        }


        /// <summary>
        /// 点击全部选项卡跳转至指定页面并展示所有事项
        /// </summary>
        private void StatPanelNavigateFunc(StatPanelInfoModel statPanel)
        {
            if (statPanel == null || string.IsNullOrEmpty(statPanel.ViewName))
                return;
            else
            {
                var param = new NavigationParameters();
                int index=0;

                //传递参数
                if (statPanel.ItemName == "全部")
                {
                    index = 1;
                    param.Add("SelectedIndex", 2);
                }

                if (statPanel.ItemName == "已完成")
                {
                    index = 1;
                    param.Add("SelectedIndex", 1);
                }
                if (statPanel.ItemName == "备忘录")
                {
                    index = 2;
                    param.Add("SelectedIndex", 2);
                }

                regionManager.RequestNavigate("MainViewRegion", statPanel.ViewName, callback =>
                {
                    journal = callback.Context.NavigationService.Journal;//将记录放入记录栈中
                    int newIndex = index;
                    eventAggregator.GetEvent<SelectedIndexChangedEvent>().Publish(newIndex);
                }, param);
            }
        }


        #endregion


        #region IConfirmNavigationRequest接口实现---初始化用户以及时间信息

        private string _welcomeInfo;

        public string WelcomeInfo
        {
            get { return _welcomeInfo; }
            set
            {
                _welcomeInfo = value;
                RaisePropertyChanged();
            }
        }


        public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
        {
            //拦截是否导航
            continuationCallback?.Invoke(true);//必须为true，否则就被拦截了
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            //导航进入时初始化的一些信息
            string userName = navigationContext.Parameters.GetValue<string>("LoginName");
            string date = DateTime.Now.ToString("yyyy年MM月dd日");
            string[] day = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };

            WelcomeInfo = $"你好，{userName}！今天是{date}，{day[(int)DateTime.Now.DayOfWeek]}。";

            //切换导航时刷新界面信息，以同步其他界面的操作
            InitStatPanelInfoList();
            InitWaitTodoInfoList();
            InitMemoInfoList();

        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;//确实是否是导航目标
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            //导航离开时
        }

        #endregion

    }
}
